package cn.edu.sgu.www.mhxysy.service.role.impl;

import cn.edu.sgu.www.mhxysy.entity.equipment.Equipment;
import cn.edu.sgu.www.mhxysy.entity.except.Property;
import cn.edu.sgu.www.mhxysy.entity.fabao.*;
import cn.edu.sgu.www.mhxysy.entity.qiling.Qiling;
import cn.edu.sgu.www.mhxysy.entity.role.RoleAccount;
import cn.edu.sgu.www.mhxysy.entity.role.RoleAttribute;
import cn.edu.sgu.www.mhxysy.entity.role.RoleJiadian;
import cn.edu.sgu.www.mhxysy.entity.school.SchoolSkill;
import cn.edu.sgu.www.mhxysy.entity.school.SchoolSkillCategory;
import cn.edu.sgu.www.mhxysy.enums.*;
import cn.edu.sgu.www.mhxysy.exception.GlobalException;
import cn.edu.sgu.www.mhxysy.mapper.baoshi.BaoshiMapper;
import cn.edu.sgu.www.mhxysy.mapper.equipment.EquipmentAttributeMapper;
import cn.edu.sgu.www.mhxysy.mapper.equipment.EquipmentMapper;
import cn.edu.sgu.www.mhxysy.mapper.equipment.EquipmentTypeMapper;
import cn.edu.sgu.www.mhxysy.mapper.except.PropertyMapper;
import cn.edu.sgu.www.mhxysy.mapper.fabao.*;
import cn.edu.sgu.www.mhxysy.mapper.qiling.QilingAttributeMapper;
import cn.edu.sgu.www.mhxysy.mapper.qiling.QilingMapper;
import cn.edu.sgu.www.mhxysy.mapper.role.RoleAccountMapper;
import cn.edu.sgu.www.mhxysy.mapper.role.RoleAttributeMapper;
import cn.edu.sgu.www.mhxysy.mapper.role.RoleJiadianMapper;
import cn.edu.sgu.www.mhxysy.mapper.school.SchoolSkillCategoryMapper;
import cn.edu.sgu.www.mhxysy.mapper.school.SchoolSkillMapper;
import cn.edu.sgu.www.mhxysy.mapper.xingyin.XingyinAttributeMapper;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.service.role.RoleAttributeService;
import cn.edu.sgu.www.mhxysy.vo.baoshi.BaoshiVO;
import cn.edu.sgu.www.mhxysy.vo.except.AttributeVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Service
public class RoleAttributeServiceImpl implements RoleAttributeService {

	private final FabaoMapper fabaoMapper;
	private final BaoshiMapper baoshiMapper;
	private final QilingMapper qilingMapper;
	private final PropertyMapper propertyMapper;
	private final EquipmentMapper equipmentMapper;
	private final RoleAccountMapper roleAccountMapper;
	private final RoleJiadianMapper roleJiadianMapper;
	private final SchoolSkillMapper schoolSkillMapper;
	private final FabaoCategoryMapper fabaoCategoryMapper;
	private final RoleAttributeMapper roleAttributeMapper;
	private final EquipmentTypeMapper equipmentTypeMapper;
	private final FabaoAttributeMapper fabaoAttributeMapper;
	private final QilingAttributeMapper qilingAttributeMapper;
	private final XingyinAttributeMapper xingyinAttributeMapper;
	private final EquipmentAttributeMapper equipmentAttributeMapper;
	private final SchoolSkillCategoryMapper schoolSkillCategoryMapper;
	private final FabaoLiangyiAttributeMapper fabaoLiangyiAttributeMapper;
	private final FabaoLiangyiAttributeValueMapper fabaoLiangyiAttributeValueMapper;
	private final FabaoLiangyiAttributeCategoryMapper fabaoLiangyiAttributeCategoryMapper;

	@Autowired
	public RoleAttributeServiceImpl(
			FabaoMapper fabaoMapper,
			BaoshiMapper baoshiMapper,
			QilingMapper qilingMapper,
			PropertyMapper propertyMapper,
			EquipmentMapper equipmentMapper,
			RoleAccountMapper roleAccountMapper,
			RoleJiadianMapper roleJiadianMapper,
			SchoolSkillMapper schoolSkillMapper,
			FabaoCategoryMapper fabaoCategoryMapper,
			EquipmentTypeMapper equipmentTypeMapper,
			RoleAttributeMapper roleAttributeMapper,
			FabaoAttributeMapper fabaoAttributeMapper,
			QilingAttributeMapper qilingAttributeMapper,
			XingyinAttributeMapper xingyinAttributeMapper,
			EquipmentAttributeMapper equipmentAttributeMapper,
			SchoolSkillCategoryMapper schoolSkillCategoryMapper,
			FabaoLiangyiAttributeMapper fabaoLiangyiAttributeMapper,
			FabaoLiangyiAttributeValueMapper fabaoLiangyiAttributeValueMapper,
			FabaoLiangyiAttributeCategoryMapper fabaoLiangyiAttributeCategoryMapper) {
		this.fabaoMapper = fabaoMapper;
		this.baoshiMapper = baoshiMapper;
		this.qilingMapper = qilingMapper;
		this.propertyMapper = propertyMapper;
		this.equipmentMapper = equipmentMapper;
		this.roleAccountMapper = roleAccountMapper;
		this.roleJiadianMapper = roleJiadianMapper;
		this.schoolSkillMapper = schoolSkillMapper;
		this.fabaoCategoryMapper = fabaoCategoryMapper;
		this.equipmentTypeMapper = equipmentTypeMapper;
		this.roleAttributeMapper = roleAttributeMapper;
		this.fabaoAttributeMapper = fabaoAttributeMapper;
		this.qilingAttributeMapper = qilingAttributeMapper;
		this.xingyinAttributeMapper = xingyinAttributeMapper;
		this.equipmentAttributeMapper = equipmentAttributeMapper;
		this.schoolSkillCategoryMapper = schoolSkillCategoryMapper;
		this.fabaoLiangyiAttributeMapper = fabaoLiangyiAttributeMapper;
		this.fabaoLiangyiAttributeValueMapper = fabaoLiangyiAttributeValueMapper;
		this.fabaoLiangyiAttributeCategoryMapper = fabaoLiangyiAttributeCategoryMapper;
	}

	@Override
	public RoleAttribute selectById(String id) {
		return roleAttributeMapper.selectById(id);
	}

	@Override
	public RoleAttribute selectByRoleId(String roleId) {
		// 查询角色开启的加点
		QueryWrapper<RoleJiadian> queryWrapper = new QueryWrapper<>();

		queryWrapper.eq("role_id", roleId);
		queryWrapper.eq("open_status", OpenStatus.OPEN.getValue());

		RoleJiadian roleJiadian = roleJiadianMapper.selectOne(queryWrapper);

		if (roleJiadian != null) {
			// 通过角色ID和加点ID查询角色属性
			Map<String, Object> columnMap = new HashMap<>();

			columnMap.put("role_id", roleId);
			columnMap.put("jiadian_id", roleJiadian.getId());

			List<RoleAttribute> list = roleAttributeMapper.selectByMap(columnMap);

			if (list.size() == 1) {
				RoleAttribute roleAttribute = list.get(0);

				if (roleAttribute.getZlqd() == 0) {
					int zlqd = compute(roleId);

					roleAttribute.setZlqd(zlqd);
				}

				return roleAttribute;
			}

			throw new GlobalException(ResponseCode.CONFLICT, "数据异常，一套加点方案匹配到多条属性！");
		}

		return null;
	}

	@Override
	public RoleAttribute selectByRoleIdAndJiadianId(String roleId, String jiadianId) {
		// 通过角色ID和加点ID查询角色属性
		QueryWrapper<RoleAttribute> queryWrapper = new QueryWrapper<>();

		queryWrapper.eq("role_id", roleId);
		queryWrapper.eq("jiadian_id", jiadianId);

		return roleAttributeMapper.selectOne(queryWrapper);
	}

	/**
	 * 计算角色的治疗强度
	 * @param roleId 角色ID
	 * @return int 角色总治疗强度
	 */
	private int compute(String roleId) {
		/*
		 * 治疗强度 = 门派技能 + 装备 + 宝石 + 器灵 + 法宝 + 经脉 + 潜能果 + 星印
		 */
		AtomicInteger value = new AtomicInteger();

		// 查询角色信息
		RoleAccount roleAccount = roleAccountMapper.selectById(roleId);
		Integer grade = roleAccount.getGrade();

		// 1、查询角色的门派技能
		Map<String, Object> columnMap = new HashMap<>();

		columnMap.put("role_id", roleId);

		List<SchoolSkill> schoolSkills = schoolSkillMapper.selectByMap(columnMap);

		for (SchoolSkill schoolSkill : schoolSkills) {
			Integer skillId = schoolSkill.getSkillId();
			SchoolSkillCategory schoolSkillCategory = schoolSkillCategoryMapper.selectById(skillId);

			Integer propertyId = schoolSkillCategory.getPropertyId();

			if (propertyId != null) {
				Property property = propertyMapper.selectById(propertyId);

				if ("治疗强度".equals(property.getName())) {
					// 技能每级增加的属性值*角色等级
					BigDecimal multiply = schoolSkillCategory.getPropertyValue().multiply(
							BigDecimal.valueOf(grade)
					);

					value.addAndGet(multiply.intValue());
				}
			}
		}

		// 2、查询角色当前穿戴的装备
		QueryWrapper<Equipment> queryWrapper = new QueryWrapper<>();

		queryWrapper.eq("role_id", roleId);
		queryWrapper.eq("wear_status", WearStatus.YCD.getValue());

		List<Equipment> list = equipmentMapper.selectList(queryWrapper);

		// 计算武器和衣服的治疗强度
		if(!list.isEmpty()) {
			list.forEach(new Consumer<Equipment>() {
				@Override
				public void accept(Equipment equipment) {
					// 得到装备ID
					String equipmentId = equipment.getId();
					Integer topType = equipmentTypeMapper.selectTopType(equipment.getCategoryId());

					// 获取武器的总治疗强度（装备 + 器灵 + 宝石)
					if (EquipmentTypes.WUQI.getValue().equals(topType)) { // 武器
						List<AttributeVO> equipmentAttributes = equipmentAttributeMapper.selectAttributes(equipmentId);

						// 武器的治疗强度属性
						for (AttributeVO attribute : equipmentAttributes) {
							if ("治疗强度".equals(attribute.getPropertyName())) {
								value.addAndGet(attribute.getPropertyValue());
							}
						}

						// 2、查询装备的宝石信息
						List<BaoshiVO> selectAttributes = baoshiMapper.selectAttributes(equipmentId);

						for (BaoshiVO baoshi : selectAttributes) {
							if ("治疗强度".equals(baoshi.getPropertyName())) {
								value.addAndGet(baoshi.getPropertyValue() * baoshi.getGrade());
							}
						}

						// 3、查询装备镶嵌的器灵
						UpdateWrapper<Qiling> updateWrapper = new UpdateWrapper<>();

						updateWrapper.eq("role_id", roleId);
						updateWrapper.eq("inlay_status", InlayStatus.YXQ.getValue());

						List<Qiling> qilings = qilingMapper.selectList(updateWrapper);

						if (!qilings.isEmpty()) {
							for (Qiling qiling : qilings) {
								List<AttributeVO> attributes = qilingAttributeMapper.selectAttributes(qiling.getId());

								for (AttributeVO attribute : attributes) {
									if ("治疗强度".equals(attribute.getPropertyName())) {
										value.addAndGet(attribute.getPropertyValue());
									}
								}
							}
						}

						// ...法宝 + 经脉 + 潜能果
					} else if (EquipmentTypes.YIJIA.getValue().equals(topType)) { // 衣甲
						// 获取衣服的宝石
						List<BaoshiVO> attributes = baoshiMapper.selectAttributes(equipmentId);

						// 如果是昆仑玉
						for (BaoshiVO baoshi : attributes) {
							if ("治疗强度".equals(baoshi.getPropertyName())) {
								value.addAndGet(baoshi.getPropertyValue() * baoshi.getGrade());
							}
						}
					}
				}
			});
		}

		// 3、查询角色佩戴的法宝
		columnMap.put("wear_status", WearStatus.YCD.getValue());

		List<Fabao> fabaos = fabaoMapper.selectByMap(columnMap);

		if (!fabaos.isEmpty()) {
			for (Fabao fabao : fabaos) {
				// 查询法宝类型信息
				Integer categoryId = fabao.getCategoryId();
				FabaoCategory fabaoCategory = fabaoCategoryMapper.selectById(categoryId);

				if (fabaoCategory.getRelateType() != null
						&& fabaoCategory.getRelateType() == 1
						&& RelateTypes.GLJS.getValue().equals(fabaoCategory.getRelateType())) {
					// 查询法宝属性
					columnMap.clear();

					columnMap.put("fabao_id", categoryId);

					List<FabaoAttribute> fabaoAttributes = fabaoAttributeMapper.selectByMap(columnMap);

					if (!fabaoAttributes.isEmpty()) {
						for (FabaoAttribute fabaoAttribute : fabaoAttributes) {
							Integer propertyId = fabaoAttribute.getPropertyId();

							if (propertyId != null) {
								Property property = propertyMapper.selectById(propertyId);

								if ("治疗强度".equals(property.getName())) {
									BigDecimal multiply = fabaoAttribute.getPropertyValue().multiply(
											BigDecimal.valueOf(fabao.getGrade())
									);

									// 关联了角色等级
									multiply = multiply.multiply(BigDecimal.valueOf(grade));

									value.addAndGet(multiply.intValue());
								}
							}
						}
					}
				}

				// 查询法宝的两仪属性
				columnMap.clear();

				columnMap.put("fabao_id", fabao.getId());

				List<FabaoLiangyiAttribute> liangyiAttributes = fabaoLiangyiAttributeMapper.selectByMap(columnMap);

				for (FabaoLiangyiAttribute liangyiAttribute : liangyiAttributes) {
					FabaoLiangyiAttributeCategory fabaoLiangyiAttributeCategory
							= fabaoLiangyiAttributeCategoryMapper.selectById(liangyiAttribute.getLiangyiId());
					Integer propertyId = fabaoLiangyiAttributeCategory.getPropertyId();

					if (propertyId != null) {
						Property property = propertyMapper.selectById(propertyId);

						if ("治疗强度".equals(property.getName())) {
							Integer valueId = liangyiAttribute.getValueId();
							FabaoLiangyiAttributeValue fabaoLiangyiAttributeValue = fabaoLiangyiAttributeValueMapper.selectById(valueId);

							BigDecimal multiply = fabaoLiangyiAttributeValue.getPropertyValue().multiply(
									BigDecimal.valueOf(fabaoLiangyiAttributeCategory.getMax())
							);
							// 关联了角色等级
							if (fabaoLiangyiAttributeCategory.getRelateGrade() == 1
									&& RelateTypes.GLJS.getValue().equals(fabaoLiangyiAttributeCategory.getRelateType())) {
								multiply = multiply.multiply(BigDecimal.valueOf(grade));
							}
							// 百分数
							if (fabaoLiangyiAttributeCategory.getIsPercent() == 1) {
								multiply = multiply.divide(BigDecimal.valueOf(100), BigDecimal.ROUND_DOWN);
							}

							value.addAndGet(multiply.intValue());
						}
					}
				}
			}
		}

		// 4、查询星印的治疗强度属性
		Integer zlqd = xingyinAttributeMapper.selectZlqd(roleId);

		if (zlqd > 0) {
			value.addAndGet(zlqd);
		}

		// 5、查询角色的潜能果

		// 6、查询角色的奇经八脉

		return value.get();
	}

}